package com.zxcl.strategy.impl;


import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zxcl.config.WxAuthConfig;
import com.zxcl.constant.AuthConstant;
import com.zxcl.domain.LoginMember;
import com.zxcl.mapper.LoginMemberMapper;
import com.zxcl.model.SecurityUser;
import com.zxcl.strategy.LoginStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * 描述: [会员策略接口]
 * 作者: zxcl
 */
@Service(AuthConstant.MEMBER_LOGIN)
public class MemberLoginStrategy implements LoginStrategy {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private WxAuthConfig wxAuthConfig;

    @Autowired
    private LoginMemberMapper loginMemberMapper;


    /**
     * 小程序登录的方法
     * 1.拿openId （appid/appsecret/code）
     * 2.自定义登录结果
     * wxd3b90c3acfea33be
     * 1f768ecece8e4eeceadcbb8cde1c0a94
     * GET
     * https://api.weixin.qq.com/sns/jscode2session
     * https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code
     *
     * @param username
     * @return
     */
    @Override
    public UserDetails realLogin(String username) {
        System.out.println("会员策略,只是在控制台输出");
        //进行替换
        String realWxAuthUrl = String.format(wxAuthConfig.getUrl(), wxAuthConfig.getAppId(), wxAuthConfig.getAppSecret(), username);
        //开始发get请求,把它转换成String
        String wxAuthStr = restTemplate.getForObject(realWxAuthUrl, String.class);
        System.out.println(wxAuthStr);
        JSONObject jsonObject = JSON.parseObject(wxAuthStr);
        //写成这样就是因为返回的数据中的key叫 openid
        String openId = jsonObject.getString("openid");

        //先看一下是不是空文本
        if (!StringUtils.hasText(openId)) {
            throw new InternalAuthenticationServiceException("登录异常，请重新进入");
        }
        // 先拿用户的身份信息， 查询数据库 看这个人是否来过 ，如果有 则直接返回这个用户对象
        // 如果没有，帮他注册一个 再返回
        LoginMember loginMember = loginMemberMapper.selectOne(new LambdaQueryWrapper<LoginMember>()
                .eq(LoginMember::getOpenId, openId)
        );
        //如果不存在就注册一下
        if (ObjectUtils.isEmpty(loginMember)) {
            // 静默注册
            loginMember = registerMember(openId);
        }
        else {
            //设置一下最后的登录时间
            loginMember.setUserLasttime(new Date());
            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = requestAttributes.getRequest();
            //设置一下它的最后登录ip
            loginMember.setUserLastip(request.getRemoteAddr());
        }
        // 统一封装返回结果
        SecurityUser securityUser = new SecurityUser();
        securityUser.setStatus(loginMember.getStatus());
        securityUser.setUserId(loginMember.getId());
        securityUser.setLoginType(AuthConstant.MEMBER_LOGIN);
        securityUser.setUsername(openId);
        securityUser.setOpenId(openId);
        securityUser.setPassword("$2a$10$ZuNSrJ0vrevLil2oCb0LeuI7ALWo5MdmzlbQcmShzimgqpjVzl8c."); // WECHAT
        //这里是和前端 http.js中传来的密码保持一致性的加密
        return securityUser;
    }



    /**
     * 静默注册
     * @param openId
     * @return
     */
    private LoginMember registerMember(String openId) {

        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        //用来获取最后登录的ip注册ip
        HttpServletRequest request = requestAttributes.getRequest();
        LoginMember loginMember = new LoginMember();
        loginMember.setOpenId(openId);
        loginMember.setCreateTime(new Date());
        loginMember.setUpdateTime(new Date());
        loginMember.setStatus(1);
        loginMember.setUserLasttime(new Date());
        // 业务处理
        loginMember.setScore(0); //设置积分
        loginMember.setUserRegip(request.getRemoteAddr());
        loginMember.setUserLastip(request.getRemoteAddr());
        loginMemberMapper.insert(loginMember);
        return loginMember;

    }
}


